#ifndef cope_timer_h
#define cope_timer_h

//#include <packet.h>
#include <scheduler.h>
#include <assert.h>

/*
 * If no packet sent out during this peroid, a control packet will be triggered
 */
#define CTRL_PKT_PEROID       2.0 //10s 

class COPE;
class Packet;
class CopeTimer : public Handler {
 public:
 CopeTimer(COPE* cope) : cope_(cope) {
	busy_ = paused_ = 0;
	stime_ = rtime_ = 0.0;
    }
    virtual ~CopeTimer() {}
    virtual void handle(Event *e) = 0;
    
    virtual void start(double time);
    virtual void stop(void);
    virtual void pause(void) { assert(0); }
    virtual void resume(void) { assert(0); }
    
    inline int busy(void) { return busy_; }
    inline int paused(void) { return paused_; }
    inline double expire(void) {
	return ((stime_ + rtime_) - Scheduler::instance().clock());
    }
    
 protected:
    COPE* cope_;
    int busy_;
    int	paused_;
    Event event_;
    double stime_;	// start time
    double rtime_;	// remaining time    
};
	
class NonAckTimer : public CopeTimer {
 public:
 NonAckTimer(COPE* cope) : CopeTimer(cope) {
	nonack_nodeid_ = 0; // it's the same whether this exists?
	nonack_local_seqnum_ = 0;
    }
    ~NonAckTimer() {}
    
    void handle(Event* e);
    void start(double time);
    void start(double time, int nodeid, u_int16_t local);
    void stop(void);
    //    void stop(Packet* p);

    /*
     * These two variables are used to store each packet's information,
     * when time out, the handle(Event* e) function knows to retransmit
     * which packet.
     */
    int nonack_nodeid_; // neighbor's node id
    u_int16_t nonack_local_seqnum_; // local sequence number
};

class CtrlPktTimer : public CopeTimer {
 public:
 CtrlPktTimer(COPE * cope) : CopeTimer(cope) {
  }
  ~CtrlPktTimer();
  void start(double time);  
  void stop(void);
  void handle(Event* e);
};
#endif

